package com.rop.system.service.impl;


import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rop.model.system.SysMenu;
import com.rop.model.system.SysRoleMenu;
import com.rop.model.vo.AssignMenuVo;
import com.rop.model.vo.RouterVo;
import com.rop.result.ResultCodeEnum;
import com.rop.system.exception.BizException;
import com.rop.system.mapper.SysMenuMapper;
import com.rop.system.mapper.SysRoleMenuMapper;
import com.rop.system.service.SysMenuService;
import com.rop.system.util.MenuHelper;
import com.rop.system.util.RouterHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author rop
 * @since 2023-04-24
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    /**
     * 菜单列表
     * @return 结果
     */
    @Override
    public List<SysMenu> findNodes() {
        // 获取所有菜单
        List<SysMenu> sysMenuList = baseMapper.selectList(null);

        // 所有菜单数据转换要求数据格式
        return MenuHelper.buildTree(sysMenuList);
    }

    /**
     * 删除菜单
     * @param id 被选中菜单id
     * @return 删除结果
     */
    @Override
    public boolean removeMenuById(Long id) {
        // 查询被删除菜单下是否存在菜单
        QueryWrapper<SysMenu> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", id);
        List<SysMenu> sysMenuChildrenList = baseMapper.selectList(wrapper);
        if (CollUtil.isNotEmpty(sysMenuChildrenList)) {
            BizException.error(ResultCodeEnum.FAIL.getCode(), "请先删除子菜单");
        }

        // 到此，该菜单下不存在子菜单
        int rows = baseMapper.deleteById(id);

        return rows > 0 ? Boolean.TRUE : Boolean.FALSE;
    }

    /**
     * 根据角色id获取菜单
     * @param roleId 角色id
     * @return 菜单集合
     */
    @Override
    public List<SysMenu> findMenuByRoleId(Long roleId) {
        // 获取所有菜单 status == 1
        QueryWrapper<SysMenu> wrapperMenu = new QueryWrapper<>();
        wrapperMenu.eq("status", 1);
        List<SysMenu> sysMenuList = baseMapper.selectList(wrapperMenu);

        // 根据角色id查询 角色分配过的菜单列表
        QueryWrapper<SysRoleMenu> wrapperRoleMenu = new QueryWrapper<>();
        wrapperRoleMenu.eq("role_id", roleId);
        List<SysRoleMenu> sysRoleMenuList = sysRoleMenuMapper.selectList(wrapperRoleMenu);

        // 从上一步查询列表中，获取角色分配所有菜单id
        List<String> menuId = sysRoleMenuList.stream()
                .map(SysRoleMenu::getMenuId)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toList());

        // 数据处理：isSelect 选中--true，否则--false
        // 拿着分配菜单的id 和 所有菜单id比对 有相同的，让isSelect值为true
        for (SysMenu sysMenu : sysMenuList) {
            sysMenu.setSelect(menuId.contains(sysMenu.getId()) ? Boolean.TRUE : Boolean.FALSE);
        }

        // 为了最终显示，转换为树形结构 MenuHelper实现
        return MenuHelper.buildTree(sysMenuList);
    }

    @Override
    public boolean doAssign(AssignMenuVo assignMenuVo) {
        // 先删除原有的菜单
        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", assignMenuVo.getRoleId());
        sysRoleMenuMapper.delete(queryWrapper);

        // 添加新的菜单
        Integer rows = 0;
        if (CollUtil.isNotEmpty(assignMenuVo.getMenuIdList())) {
            rows = sysRoleMenuMapper.batchInsert(assignMenuVo);
        }
        return rows < 0 ? Boolean.FALSE : Boolean.TRUE;
    }

    /**
     * 获取用户菜单权限数据
     * @param userId 用户id
     * @return 用户的菜单
     */
    @Override
    public List<RouterVo> getUserMenuList(Long userId) {
        // 获取菜单权限数据
        List<SysMenu> sysMenuList = getSysMenus(userId);

        // 构建树形结构
        List<SysMenu> sysMenuTreeList = MenuHelper.buildTree(sysMenuList);

        // 对路由构建树形
        List<RouterVo> routerVos = null;
        if (CollUtil.isNotEmpty(sysMenuList)) {
            routerVos = RouterHelper.buildRouters(sysMenuTreeList);
        }

        return routerVos;
    }

    /**
     * 获取用户按钮权限数据
     * @param userId 用户id
     * @return 用户的按钮权限
     */
    @Override
    public List<String> getUserButtonList(Long userId) {
        // 获取菜单权限数据
        List<SysMenu> sysMenus = getSysMenus(userId);

        // 获取按钮数据 type == 2
        return sysMenus.stream()
                .filter(t -> Objects.equals(t.getType(), 2))
                .map(SysMenu::getPerms)
                .collect(Collectors.toList());
    }

    /**
     * 根据用户id获取菜单
     * @param userId 用户id
     * @return 菜单权限数据
     */
    private List<SysMenu> getSysMenus(Long userId) {
        List<SysMenu> sysMenuList = null;
        if ("1".equals(String.valueOf(userId))) {
            QueryWrapper<SysMenu> wrapper = new QueryWrapper<>();
            wrapper.eq("status", 1);
            wrapper.orderByAsc("sort_value");
            sysMenuList = baseMapper.selectList(wrapper);
        } else {
            // 如果userId值不是1，代表其他类型用户，查询这个用户权限
            sysMenuList = baseMapper.findMenuListByUserId(userId);
        }
        return sysMenuList;
    }
}
